package com.baosight.risk.common.quartz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baosight.risk.api.fltd.FltdProcessService;
import com.baosight.risk.api.zbaa.IZbaaTargetService;
import com.baosight.risk.api.zbaa.IZbaaTargetValueService;
import com.baosight.risk.common.aspects.factory.AsyncFactory;
import com.baosight.risk.common.email.service.EmailService;
import com.baosight.risk.common.manager.AsyncManager;
import com.baosight.risk.common.utils.DateUtils;
import com.baosight.risk.common.utils.IDGenerator;
import com.baosight.risk.mapper.system.SysInterfaceDataLogMapper;
import com.baosight.risk.mapper.zbaa.ZbaaTargetSendMapper;
import com.baosight.risk.service.system.entity.SysInterfaceDataLogEntity;
import com.baosight.risk.service.system.entity.SysOperLog;
import com.baosight.risk.service.zbaa.entity.ZbaaTarget;
import com.baosight.risk.service.zbaa.entity.ZbaaTargetSend;
import com.baosight.risk.service.zbaa.entity.ZbaaTargetValue;
import com.baosight.risk.webservice.TargetWebService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author cuishihao
 * <p>
 * 定时任务
 * 调用接口获取内部指标数据值
 */
@Slf4j
@Component("targetTask")
public class TargetTask {

    @Autowired
    private TargetWebService targetWebService;

    @Autowired
    private IZbaaTargetValueService zbaaTargetValueService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private IZbaaTargetService targetService;

    @Autowired
    private ZbaaTargetSendMapper targetSendMapper;

    @Autowired
    SysInterfaceDataLogMapper logMapper;

    @Autowired
    private FltdProcessService fltdProcessService;

    public void testParams(String params, String jobId) throws Exception {
        List<SysOperLog> logs = new ArrayList<>();
        Exception error = null;
        try {
            log.info("进入定时任务——获取内部指标方法");

            // 获取昨日日期
            String nowDate = DateUtils.format(new Date(), "yyyy-MM-dd");
            String yesterday = DateUtils.caculateTime(nowDate, "日", "1");

            try {
                //传入参数，调用指标值获取接口数据
                // String jsonString = "[{\"beginTime\":\"2019-09-11\",\"endTime\":\"2019-09-11\",\"targetNo\":\"\"}]";
                String jsonString = "[{\"beginTime\":\"" + yesterday + "\",\"endTime\":\"" + yesterday + "\",\"targetNo\":\"\"}]";
                String dataResult = targetWebService.sendRequestResult(jsonString);

                // 参数 去重 yesterday
                SysInterfaceDataLogEntity entity = new SysInterfaceDataLogEntity();

                //别忘了通过这个去重
                entity.setInYesterday(yesterday);
                List<SysInterfaceDataLogEntity> select = logMapper.select(entity);

                if (select.size() == 0){
                    entity.setId(IDGenerator.getIdStr());
                    entity.setData(dataResult);
                    entity.setInterfaceName("内部指标接口获取");
                    logMapper.insert(entity);
                }
                System.out.println("--------------->内部指标"+dataResult);

                //处理获取的接口数据
                List<ZbaaTargetValue> list = dataHandle(dataResult);

                if (list.size() > 0) {
                    // 批量插入处理后的数据
                    zbaaTargetValueService.insertValueList(list);

                    // 对订阅用户发送邮件。通知订阅值发生变化
                    emailToOrderUser(list);
                }
            } catch (Exception e) {
                String str = String.format("%s 获取 %s 内部指标数据出错！", nowDate, yesterday);
                log.info(str);
                log.info(e.toString());
            }
            log.info("定时任务——获取内部指标方法完成");
            logs.add(fltdProcessService.getLog("获取内部指标定时任务执行成功", 0, "", jobId));
        }catch (Exception e) {
            error = e;
            logs.add(fltdProcessService.getLog("获取内部指标定时任务执行失败", 1, e.getMessage(), jobId));
        }
        // 保存日志到数据库
        AsyncManager.me().execute(AsyncFactory.batchRecordOper(logs));
        if (error != null) {
            throw error;
        }


    }

    /**
     * @param list
     * @return void
     * @description 对订阅用户发送邮件, 通知订阅值发生变化
     * @author CuiShiHao
     */
    private void emailToOrderUser(List<ZbaaTargetValue> list) {
        //获取全部订阅信息
        List<ZbaaTargetSend> sendList = targetSendMapper.select(new ZbaaTargetSend());

        //遍历信息，发送邮件
        for (ZbaaTargetValue zbaaTargetValue : list) {
            String targetNo = zbaaTargetValue.getTargetNo();
            List<ZbaaTargetSend> orderList = sendList.stream().filter(o -> o.getTargetNo().equals(targetNo)).collect(Collectors.toList());

            for (int i = 0; i < orderList.size(); i++) {
                String subject = "订阅的指标更新提示";
                String message = "您订阅的指标" + zbaaTargetValue.getTargetName() + "在" + DateUtils.format(zbaaTargetValue.getCreateTime(), "yyyy-MM-dd") + "更新为" + zbaaTargetValue.getTargetValue() + ";最近指标趋势为null" ;
                //调用邮箱接口发邮件。
                int result = emailService.sendEmail(orderList.get(i).getUserCode(), subject, message, "");
                System.out.println(result);
            }
        }
    }

    /**
     * @param dataResult
     * @return
     * @description 处理接口中获得的指标数据
     * @author CuiShiHao
     */
    private List<ZbaaTargetValue> dataHandle(String dataResult) {

        //处理后数据（仅插入可以对应到targetNo的数据）
        List<ZbaaTargetValue> resultList = new ArrayList<>();
        //查询所有指标数据
        List<ZbaaTarget> targetList = targetService.getTargetList(new ZbaaTarget());

        //处理指标数据，更新targetNo
        JSONObject jsonObject = JSONObject.parseObject(dataResult);
        JSONArray data = jsonObject.getJSONArray("data");
        List<ZbaaTargetValue> list = JSONObject.parseArray(data.toJSONString(), ZbaaTargetValue.class);
        for (ZbaaTargetValue zbaaTargetValue : list) {
            zbaaTargetValue.setId(IDGenerator.getIdStr());
            zbaaTargetValue.setPeriodNo(zbaaTargetValue.getTargetPeriod());

            for (ZbaaTarget zbaaTarget : targetList) {
                if (zbaaTarget.getTargetNo().equals(zbaaTargetValue.getTargetNo())) {

                    // 根据周期处理TargetPeriod
                    String targetPeriodName = zbaaTarget.getTargetPeriodName();
                    String periodNo = handleTargetPeriod(zbaaTargetValue.getTargetPeriod(), targetPeriodName);
                    zbaaTargetValue.setPeriodNo(periodNo);
                    zbaaTargetValue.setAcctYear(periodNo.substring(0, 4));
                    if (periodNo.length() > 4) {
                        zbaaTargetValue.setAcctPeriod(periodNo.substring(4, 6));
                    }
                    // 填充代码逻辑中非必要参数
                    zbaaTargetValue.setTargetPeriod(zbaaTarget.getTargetPeriod());
                    zbaaTargetValue.setTargetPeriodName(zbaaTarget.getTargetPeriodName());
                    zbaaTargetValue.setRiskSource("N");
                    zbaaTargetValue.setRiskSourceName("内部指标");
                    resultList.add(zbaaTargetValue);
                    break;
                }
            }
        }
        return resultList;
    }

    /**
     * @param periodNo         传入的periodNo
     * @param targetPeriodName 周期名称
     * @return
     * @description 描述
     * @author CuiShiHao
     */
    private String handleTargetPeriod(String periodNo, String targetPeriodName) {

        String result = "";
        switch (targetPeriodName) {
            case "年":
                result = periodNo.substring(0, 4);
                break;
            case "月":
                result = periodNo.substring(0, 6);
                break;
            case "日":
                result = periodNo;
                break;
            case "季":
                result = dealQuarter(periodNo);
                break;
        }
        return result;
    }

    /**
     * @param periodNo 周期
     * @return
     * @description 描述
     * @author CuiShiHao
     */
    public String dealQuarter(String periodNo) {
        String year = periodNo.substring(0, 4);
        String month = periodNo.substring(5, 6);
        String result = "";
        switch (month) {
            case "1":
            case "2":
            case "3":
                result = "Q1";
                break;
            case "4":
            case "5":
            case "6":
                result = "Q2";
                break;
            case "7":
            case "8":
            case "9":
                result = "Q3";
                break;
            case "10":
            case "11":
            case "12":
                result = "Q4";
                break;
        }
        return year + result;
    }

    public void testNoParams() {
        log.error("执行无参方法");
    }
}
